const { src, dest, series, watch, parallel } = require('gulp');
// js
const babel = require('gulp-babel')
const concat = require('gulp-concat')
const gulify = require('gulp-uglify')
// css
const gulpSass = require('gulp-sass')
const mincss = require('gulp-csso')
// html
const htmlMin = require('gulp-htmlmin')
//压缩处理图片
const imagemin = require('gulp-imagemin')
// webserver == http.createServer
const webserver = require('gulp-webserver')
// 解析post参数
const bodyParser = require('body-parser')

const path = require('path')
const url = require('url')
const userData = require('./src/mock/user.json')
const movieData = require('./src/mock/movie.json')
const fs = require('fs')

// 定义一个js的任务
function js() {
  return src('src/js/*.js')
    .pipe(babel({
      presets: ['@babel/env']
    }))
    .pipe(concat('app.js'))
    .pipe(gulify())
    .pipe(dest('dist/js'))
}

function sass() {
  return src('src/css/*.scss')
    .pipe(gulpSass())
    .pipe(concat('app.css'))
    .pipe(mincss())
    .pipe(dest('dist/css'))
}

// 处理图片
function image() {
  return src('src/img/*.png')
    .pipe(imagemin({
      progressive: true, //类型：Boolean 默认：false 无损压缩jpg图片
    }))
    .pipe(dest('dist/img'));
}

function html() {
  return src('src/*.html')
    .pipe(htmlMin({
      collapseWhitespace: true, // //压缩HTML
      minifyJS: true,  //压缩页面JS
      minifyCSS: true  //压缩页面CSS
    }))
    .pipe(dest('dist/'))
}

// const db = [
//   {
//     username: "devin",
//     password: "123"
//   }
// ]


function server() {
  return src('src')
    .pipe(webserver({
      livereload: true, // 热更新
      // directoryListing: true,
      // open: true, // 自动打开页面
      port: 9000,
      // 中间件， 拦截请求 返回响应 req , res
      middleware: [
        // 解析form表单提交格式
        // 加上 extended: false 就会把name=devin&age=123 这种格式转变为 { name:devin, age: 123 }这种格式
        bodyParser.urlencoded({
          extended: false
        }),
        // 解析json提交的参数
        bodyParser.json(),
        (req, res, next) => {
          /**
           * @function [解析参数-处理接口]
           * @param { 登陆接口 username password } /api/login
           * @param { 注册接口 username password } /api/register
           * @param { url.parse(requestUrl, true) }  req.query = pathname.query;
           * @param { bodyParser解析post参数 } req.body;
           * 
           * 最终 参数获取： 
           * get： req.query 
           * post: req.body
           * 
           * @function [写接口：获取参数，根据参数返回数据]
          */
          // 登陆 注册接口 
          const requestUrl = req.url; // 完整的请求地址
          // 如果url.parse()的第二个参数为true的话，那么前端带过来的参数就会以对象形式展现出来
          const pathname = url.parse(requestUrl, true) // 解析后的请求地址
          // 请求地址
          const address = pathname.pathname;
          // 请求方式
          const method = req.method;
          // get参数
          req.query = pathname.query;
          // 登陆
          if (method === 'POST' && address === '/api/login') {
            // 除了获取参数的方式不一样，其他代码都和get方式保持一直
            const { username, password } = req.body;
            const flag = userData.some(val => val.username === username && val.password === password)
            if (flag) { // 存在
              res.end(JSON.stringify({
                code: 0,
                msg: 'success'
              }))
            } else { // 不存在
              res.end(JSON.stringify({
                code: -1,
                msg: 'fail'
              }))
            }
            return
          }
          // 注册 
          if (method === 'POST' && address === '/api/register') {
            const { username, password } = req.body;
            const flag = userData.some(val => val.username === username && val.password === password)
            if (flag) { // 存在
              res.end(JSON.stringify({
                code: -1,
                msg: '账号已经被注册了'
              }))
            } else { // 不存在
              // 添加到数据库
              userData.push(req.body)
              const isAdd = fs.writeFileSync('./src/mock/user.json', JSON.stringify(userData))
              if (!isAdd) {
                res.end(JSON.stringify({
                  code: 0,
                  msg: 'success'
                }))
              } else {
                res.end(JSON.stringify({
                  code: -1,
                  msg: 'fail'
                }))
              }
            }
            return; // 必须return,否则会报错， 设置两次的错
          }

          // 列表接口
          if (method === 'GET' && address === '/api/list') {
            res.end(JSON.stringify(movieData))
            return
          }

          // // 分页
          // if (method === 'GET' && address === '/api/page') {
          //   const { page, size } = req.query;
          //   return;
          // }
          // // 过滤
          // if (method === 'GET' && address === '/api/search') {
          // const { key } = req.query;
          //   return;
          // }

          // 设置请求头
          // res.setHeader('Content-Type', 'application/json');
          if (method === 'GET' && address === '/api/login') {
            const { username, password } = req.query
            const flag = userData.some(val => val.username === username && val.password === password)
            if (flag) {
              res.end(JSON.stringify({
                code: 0,
                msg: 'success'
              }))
            } else {
              res.end(JSON.stringify({
                code: 0,
                msg: 'fail'
              }))
            }
            return;
          }

          // if (method === 'GET' && address === '/api/login') {
          //   res.end(`
          //    requestUrl-完整路径: ${requestUrl}\n
          //    pathname-请求解析后路径: ${JSON.stringify(pathname)} \n
          //    address-请求地址: ${address} \n
          //    method-请求方式: ${method}\n
          //    params-get参数：${JSON.stringify(params)}\n
          //   `)
          // }
          next() // 下一针
        }],
    }));
}


function watchFile() {
  // 监听文件变化，一旦文件变化，就执行后面的任务
  watch('./src/index.html', series(html))
  watch('./src/css/*.scss', series(sass))
  watch('./src/js/*.js', series(js))
  watch('./src/img/*.png', series(image))
}

// module.exports = {
//   js,
//   sass,
//   html,
//   server
// }

exports.default = series(html, js, sass, image, server, watchFile);
